// 处理和登录相关的网络请求
import { request, HttpMethod, restartTimes, RequestConfig } from './request'
import { baseUrl } from './config'
import { mySleep, validateNull } from '../util'

const basicAuth = 'Basic dGVzdDp0ZXN0';
const FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded'

export function getOpenId() {
  return new Promise(function (reslove, reject) {
    wx.login({
      success(res) {
        console.log('dev code =', res.code)
        if (res.code) {
          // 发起网络请求
          wx.request({
            url: baseUrl + '/patient/patientLogin/get_wx_open_id/' + res.code,
            method: "GET",
            success: (response: any) => {
              console.log('获取openId接口返回:', response);
              // 检查返回数据
              if (!response.data) {
                console.error('返回数据为空:', response);
                reject(new Error('返回数据为空'));
                return;
              }
              if (response.data.code === 1) {
                console.error('获取openId失败:', response.data.msg);
                reject(new Error(response.data.msg || '获取openId失败'));
                return;
              }
              if (!response.data.data || !response.data.data.openid) {
                console.error('openid数据不存在:', response.data);
                reject(new Error('openid数据不存在'));
                return;
              }
              wx.setStorageSync("openid", response.data.data.openid)
              reslove(response.data.data.openid)
            },
            fail: (err: any) => {
              console.log('获取openId网络错误', err);
              reject(err);
            }
          })
        } else {
          console.log('登录失败！' + res.errMsg)
        }
      }
    });
  })
}

export async function autoLogin(times: number = restartTimes) {
  // 先判断是否存在openid
  var openid = wx.getStorageSync("openid");
  if (validateNull(openid)) {
    await getOpenId();
    openid = wx.getStorageSync("openid");
  }
  console.log('openid为', openid);
  return new Promise((reslove, reject) => {
    wx.request({
            url: baseUrl + '/patient/patientLogin/custom_login',
      method: "POST",
      data: { openId: openid },
      success: async (res: any) => {
        const response = res.data
        if (response.code == 1) {
          if (response.msg.indexOf("绑定手机") != -1) {
            // 需要绑定手机，跳转到注册页面
            console.log("需要绑定手机，跳转到注册页面", response)
            wx.reLaunch({
              url: '/pages/login/signup/index',
            })
          } else if (response.msg.indexOf("等待一段时间") != -1) {
            await mySleep(500);
            if (times > 0) {
              autoLogin(times - 1).then((resTmp:any) => {
                console.log("成功登录1:", resTmp);
                // 设置token
                wx.setStorageSync("access_token", resTmp.data.access_token);
                wx.setStorageSync("refresh_token", resTmp.data.refresh_token);
                
                // 保存用户信息
                if (resTmp.data.user_info) {
                  if (resTmp.data.user_info.patientUid) {
                    wx.setStorageSync("patientUid", resTmp.data.user_info.patientUid);
                  }
                  if (resTmp.data.user_info.phoneNumber) {
                    wx.setStorageSync("phoneNumber", resTmp.data.user_info.phoneNumber);
                  }
                }
                
                reslove(resTmp)
              })
            } else {
              wx.showToast({
                title: '请稍后重新登录',
                icon: "loading",
              })
            }
          } else {
            wx.showModal({
              title: '登录错误',
              content: response.msg,
            })
          }
        } else {
          // 登录成功
          wx.setStorageSync("access_token", response.data.access_token);
          wx.setStorageSync("refresh_token", response.data.refresh_token);
          
          // 保存用户信息（如果后端返回了的话）
          if (response.data.user_info) {
            if (response.data.user_info.patientUid) {
              wx.setStorageSync("patientUid", response.data.user_info.patientUid);
              console.log("已保存 patientUid:", response.data.user_info.patientUid);
            }
            if (response.data.user_info.phoneNumber) {
              wx.setStorageSync("phoneNumber", response.data.user_info.phoneNumber);
              console.log("已保存 phoneNumber:", response.data.user_info.phoneNumber);
            }
          }
          
          // 登录成功
          wx.switchTab({
            url: '/pages/home/index'
          });
          console.log("成功登录2:", response);
          reslove(response);
        }
        reslove(response);
      },
      fail: (err: any) => {
        console.log('登录接口出现错误');
        reject(err)
      }
    })
  })
}

// 获取手机号和绑定手机号需要拆解，不然过于浪费绑定次数
export async function getPhoneNumber(data: object) {
  const config = <RequestConfig>{
    url: '/patient/patientLogin/get_phone_number',
    method: HttpMethod.POST,
    data: data,
    skipToken: true,
  }
  return request(config);
}

export async function bindPhoneNumber(data: object) {
  const config = <RequestConfig>{
    url: '/patient/patientLogin/bind_phone_number',
    method: HttpMethod.POST,
    data: data,
    skipToken: true,
  }
  return request(config);
}

// 用户登录（手机号+密码）
export async function userLogin(data: { phoneNumber: string, password: string }) {
  const config = <RequestConfig>{
    url: '/patient/patientLogin/phone_login',
    method: HttpMethod.POST,
    data: data,
    skipToken: true,
  }
  return request(config);
}


/**
 * 校验令牌，若有效期小于半小时自动续期
 * @param refreshLock
 */
export const checkToken = (refreshTime: any, refreshLock: any) => {
  var access_token = wx.getStorageSync("access_token");
  return new Promise((reslove, reject) => {
    const config = <RequestConfig>{
      url: '/auth/token/check_token',
      skipToken: true,
      header: {
        Authorization: basicAuth,
        'Content-Type': FORM_CONTENT_TYPE,
      },
      method: HttpMethod.GET,
      data: { token: access_token },
    }
    request(config, false).then((res: any) => {
       console.log("验证token返回值", res)
      if (validateNull(res) || res.code == 1) {
        clearInterval(<number>refreshTime.value);
        console.log("token验证失败", res);
        reject(res)
      }
      const expire = Date.parse(res.expiresAt);
      if (expire) {
        const expiredPeriod = expire - new Date().getTime();
        //小于半小时自动续约
        if (expiredPeriod <= 30 * 60 * 1000) {
          if (!refreshLock.value) {
            refreshLock.value = true;
            refreshTokenApi()?.then((res: any) => {
              // 存储token信息
              wx.setStorageSync("access_token", res.access_token);
              wx.setStorageSync("refresh_token", res.refresh_token);
              console.log("token验证成功", res);
              reslove(res)
            }).catch((err: any) => {
              clearInterval(<number>refreshTime.value);
              console.log("token验证失败2", err);
              reject(err)
            });
            refreshLock.value = false;
          }
        } else {
          console.log("token验证成功2", res);
          // 重新设置token
          wx.setStorageSync("access_token", res.access_token);
          wx.setStorageSync("refresh_token", res.refresh_token);
          reslove(res)
        }
      } else {
        // console.log("token验证成功3", res);
        wx.setStorageSync("access_token", res.access_token);
        wx.setStorageSync("refresh_token", res.refresh_token);
        reslove(res)
      }
    }).catch((err: any) => {
      clearInterval(<number>refreshTime.value);
      // 失败需要自动登录
      autoLogin().then((res: any) => {
        console.log("token验证成功4", res);
        // 重新设置token
        wx.setStorageSync("access_token", res.data.access_token)
        wx.setStorageSync("refresh_token", res.data.refresh_token)
        reslove(res);
      }).catch((err: any) => {
        console.log("token验证失败3", err);
        reject(err);
      })
    })
  })
}

export function refreshTokenApi() {
  var refresh_token = wx.getStorageSync("refresh_token");
  return new Promise((resolve, reject) => {
    if (validateNull(refresh_token)) {
      reject({ code: 1, msg: "不存在refresh_token" })
    }
    const grant_type = 'refresh_token';
    const scope = 'server';
    const config = <RequestConfig>{
      url: '/auth/oauth2/token',
      skipToken: true,
      header: {
        Authorization: basicAuth,
        'Content-Type': FORM_CONTENT_TYPE,
      },
      method: HttpMethod.POST,
      data: { refresh_token, grant_type, scope },
    }
    request(config).then((res: any) => {
      resolve(res);
    }).catch((err: any) => {
      reject(err);
    })
  })
}

const refreshTime = {
  value: <number | null>null,
}
const refreshLock = {
  value: false,
}

export const autoRefreshToken = () => {
  // HTTP返回异常也没有问题小程序没有认为40x为异常，而是在success函数中执行
  refreshTime.value = setInterval(() => {
    checkToken(refreshTime, refreshLock);
  }, 60000);
};

// 指定单词校验
export const onceCheckToken = () => {
  return checkToken(refreshTime, refreshLock);
}
